package com.ys.service.finance.impl;

import java.math.BigDecimal;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ys.dto.AddDto;
import com.ys.entity.finance.TcwAccountCountForUser;
import com.ys.entity.finance.TcwPointTransfer;
import com.ys.entity.flow.YspModel;
import com.ys.entity.shiro.LoginUser;
import com.ys.entity.sys.TsUserInfo;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.finance.TcwUserPointFrozenRunningEnum;
import com.ys.enume.finance.TcwUserPointRunningEnum;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.finance.TcwPointTransferMapper;
import com.ys.service.finance.TcwAccountCountForUserService;
import com.ys.service.finance.TcwPointTransferService;
import com.ys.service.finance.TcwAccountCountForUserService.ChangePointDto;
import com.ys.service.finance.TcwAccountCountForUserService.ChangePointFrozenDto;
import com.ys.service.flow.YspTaskService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("tcwPointTransferService")
public class TcwPointTransferImpl implements TcwPointTransferService {
	
	@Autowired
	private TcwPointTransferMapper tcwPointTransferMapper;
	@Autowired
	private TcwAccountCountForUserService tcwAccountCountForUserService;
	@Autowired
	private YspTaskService yspTaskService;
	
	
	@Override
	@Transactional
	public R add(String bid, String userIdTo, BigDecimal point, String runningItem, String runningItemSub, Long menuId) throws Exception {
		
		LoginUser loginUser = ShiroUtils.getLoginUser();
		String userIdFrom = loginUser.getUserId();
		
		// 验证订单号
		if (new TcwPointTransfer().setBid(bid).count() > 0) {
			return R.error("该订单号已存在");
		}
		
		// 验证学分
		if (point == null) {
			return R.error("划拨数量不能为空");
		} else if (point.compareTo(BigDecimal.ZERO) <= 0) {
			return R.error("划拨数量必须大于0");
		}
		TcwAccountCountForUser account = new TcwAccountCountForUser().setUserId(userIdFrom).queryFirst();
		if (account.getPointAble().compareTo(point) < 0) {
			return R.error("剩余可用学分不足");
		}
		
		TsUserInfo userTo = new TsUserInfo().setUserId(userIdTo).queryFirst();
		if (userTo == null) {
			return R.error("接收人工号不存在");
		}
		
		// 添加学分划拨单
		TcwPointTransfer entity = null;
		{
			String userNameFrom = loginUser.getUserName();
			Integer effectStock = FlowEnum.EffectStock.NOT_EFFECT.value;
			String userNameTo = userTo.getUserName();
			entity = TcwPointTransfer.tcwPointTransfer(bid, userIdFrom, userNameFrom, point, userIdTo, userNameTo, effectStock, runningItem, runningItemSub, 1);
		}
		tcwPointTransferMapper.insert(entity);
		
		// 冻结学分
		{
			Integer type = TcwUserPointFrozenRunningEnum.Type.TRANSFER_FROM_FROZEN.value;
			Long relativeId = entity.getId();
			String userId = loginUser.getUserId();
			String userName = loginUser.getUserName();
			BigDecimal pointChangeFrozen = point.negate();
			String remark = "划拨单转出时冻结";
			ChangePointDto changePointDto = null;
			ChangePointFrozenDto changePointFrozenDto = new ChangePointFrozenDto(type, relativeId, userId, userName, pointChangeFrozen, remark);
			tcwAccountCountForUserService.change(changePointDto, changePointFrozenDto);
		}

		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, bid, createUserId);
		}
		
		return R.ok(AddDto.gotoEdit("/web/finance/tcwPointTransfer/toFlow?bid=" + entity.getBid()));
	}
	
	@Override
	@Transactional
	public R edit(Map<String, Object> params) throws Exception {
//		ThrOperateCompanyApply entity = JSON.parseObject(JSON.toJSONString(params), ThrOperateCompanyApply.class);
//		
//		// 验证编码
//		String vGsBm = entity.getVGsBm();
//		if (new ThrOperateCompanyApply().setVGsBm(vGsBm).where("A.Id != '" + params.get("id").toString() + "'").count() > 0) {
//			return R.error("公司编码【" + vGsBm + "】已存在");
//		}
//		
//		// 验证状态
//		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
//		if (ysProcInst == null) {
//			return R.error("审批数据不存在，无法编辑");
//		} else if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.INIT.value) {
//			return R.error("已流转，无法编辑");
//		}
//		
//		String vGsBmP = entity.getVGsBmP();
//		
//		// 若上级公司编码有改动，则节点值需一起变化
//		ThrOperateCompanyApply entityOld = new ThrOperateCompanyApply().setId(entity.getId()).queryFirst();
//		if (vGsBmP != null && vGsBmP.length() > 0 && !vGsBmP.equals(entityOld.getVGsBmP())) {
//			ThrOperateCompanyApply entityP = new ThrOperateCompanyApply().setId(entity.getPid()).queryFirst();
//
//			// 更新二叉树
//			Long nodeRgt = entityP.getNodeRgt();
//			hrMapper.updateThrOperateCompanyApplyNodeForInsertNode(nodeRgt, 2L);
//			
//			entity.setPid(entityP.getId());
//			entity.setFloor(entityP.getFloor() + 1);
//			entity.setNodeLft(nodeRgt);
//			entity.setNodeRgt(nodeRgt + 1);
//		}
//		
//		thrOperateCompanyApplyMapper.update(entity);
		return R.ok("操作成功");
	}

	@Override
	@Transactional
	public R delete(Long id) throws Exception {
		if (id == null) {
			return R.error("ID不能为空");
		}
		TcwPointTransfer entity = new TcwPointTransfer().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		if (!entity.getUserIdFrom().equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		
		// 删除主数据
		tcwPointTransferMapper.deleteTrue(id);
		
		// 解冻学分
		{
			Integer type = TcwUserPointFrozenRunningEnum.Type.TRANSFER_FROM_UNFROZEN.value;
			Long relativeId = entity.getId();
			String userId = entity.getUserIdFrom();
			String userName = entity.getUserNameFrom();
			BigDecimal pointChangeFrozen = entity.getPoint();
			String remark = "划拨单删除后解冻";
			ChangePointDto changePointDto = null;
			ChangePointFrozenDto changePointFrozenDto = new ChangePointFrozenDto(type, relativeId, userId, userName, pointChangeFrozen, remark);
			tcwAccountCountForUserService.change(changePointDto, changePointFrozenDto);
		}
		
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	@Override
	@Transactional
	public R flowPass(Long id, String loginUserId) throws Exception {
		
		TcwPointTransfer entity = new TcwPointTransfer().setId(id).queryFirst();
		String bid = entity.getBid();
		try {
			Flow f = yspTaskService.flowPass(bid, loginUserId);
			if (f.getCode() == Flow.Code.FAILED.value) {
				return R.error(f.getMsg());
			} else {
				if (f.getState() == Flow.State.FINISH.value) {
					flowFinish(id);
				}
				return R.ok();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.error("服务器正在开小差，请联系客服");
		}
	}

	@Override
	@Transactional
	public void flowFinish(Long id) throws Exception {
		
		TcwPointTransfer entity = new TcwPointTransfer().setId(id).queryFirst();
		
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		tcwPointTransferMapper.update(entity);
		
		// 转出人解冻学分并扣减学分
		
		// 转入人添加学分
		{
			String item = entity.getRunningItem();
			String itemSub = entity.getRunningItemSub();
			Integer type = TcwUserPointRunningEnum.Type.TRANSFER_TO.value;
			Long relativeId = entity.getId();
			String userId = entity.getUserIdTo();
			String userName = entity.getUserNameTo();
			BigDecimal pointChange = entity.getPoint();
			String remark = "划拨到账，学分划拨单号：" + entity.getBid();
			ChangePointDto changePointDto = new ChangePointDto(item, itemSub, type, relativeId, userId, userName, pointChange, remark);
			ChangePointFrozenDto changePointFrozenDto = null;
			tcwAccountCountForUserService.change(changePointDto, changePointFrozenDto);
		}
	}
}
